package com.dstz.sys.rest.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.dstz.base.api.aop.annotion.CatchErr;
import com.dstz.base.api.constant.BaseStatusCode;
import com.dstz.base.api.query.QueryFilter;
import com.dstz.base.api.query.QueryOP;
import com.dstz.base.api.response.impl.ResultMsg;
import com.dstz.base.core.id.IdUtil;
import com.dstz.base.db.model.page.PageResult;
import com.dstz.base.rest.BaseController;
import com.dstz.sys.api.jms.producer.JmsProducer;
import com.dstz.sys.core.manager.SysScheduleJobLogManager;
import com.dstz.sys.core.manager.SysScheduleJobManager;
import com.dstz.sys.core.model.SysScheduleJob;
import com.dstz.sys.core.model.SysScheduleJobLog;
import com.dstz.sys.util.RedisPubsub;
import com.dstz.sys.util.ScheduleUtil;

/**
 * 系统任务计划
 *
 * @author didi
 */
@RestController
@RequestMapping("/sys/scheduleJob")
public class SysScheduleJobController extends BaseController<SysScheduleJob> {
    @Autowired SysScheduleJobManager sysScheduleJobManager;
    @Autowired SysScheduleJobLogManager sysScheduleJobLogManager;
    @Autowired JmsProducer jmsProducer;

    /**
     * 检查是否存在
     *
     * @param name  计划名称
     * @param group 计划分组
     * @return
     */
    @PostMapping("checkExists")
    public boolean checkExists(@RequestParam(name = "name") String name, @RequestParam("group") String group) {
        return sysScheduleJobManager.exists(name, group);
    }

    /**
     * 启用任务计划
     *
     * @param id
     * @param enable
     * @return
     * @throws Exception
     */
    @CatchErr(write2response = true)
    @RequestMapping("enable")
    public ResultMsg<Void> enable(@RequestParam("id") String id, @RequestParam("enable") boolean enable) throws Exception {
		if (enable) {
        	sysScheduleJobManager.enableSysScheduleJob(id);
        	SysScheduleJob job = sysScheduleJobManager.get(id);//启用任务时需要完整的job信息
        	RedisPubsub.pub(job);
        } else {
        	sysScheduleJobManager.disableSysScheduleJob(id);
        	SysScheduleJob job = new SysScheduleJob();
        	job.setId(id);
        	job.setRunningState(SysScheduleJob.DISABLE);//禁用任务时只需要id和状态
        	RedisPubsub.pub(job);
        }
        return new ResultMsg<>(null);
    }
    
    @CatchErr(write2response = true)
    @RequestMapping("enableAll")
    public ResultMsg<Boolean> enableAll(@RequestParam(defaultValue="") Boolean enable, @RequestParam(defaultValue="false") boolean notify) throws Exception {
    	if(enable!=null) {
    		ScheduleUtil.enableAll(enable.booleanValue());
    		SysScheduleJob job = new SysScheduleJob();
    		//控制定时任务时，通知所有应用，也可以仅停止某个服务器的定时任务
    		job.setRunningState(enable.booleanValue() ? SysScheduleJob.ENABLE : SysScheduleJob.DISABLE);
    		if(notify) {
    			RedisPubsub.pub(job);
    		}
    	}
    	return new ResultMsg<>(ScheduleUtil.isStarted());
    }

    /**
     * 立即运行一次
     *
     * @param id 执行计划ID
     * @return
     * @throws Exception
     */
    @RequestMapping("runOnce")
    @CatchErr(write2response = true)
    public ResultMsg<Void> runOnce(@RequestParam("id") String id) throws Exception {
        SysScheduleJob sysScheduleJob = sysScheduleJobManager.get(id);
        sysScheduleJob.setConcurrent(true);//不必去加锁，直接测试执行
        ScheduleUtil.jobTask(sysScheduleJob).execute();
        return new ResultMsg<>(null);
    }
    
    /** 测试执行 */
    @RequestMapping("runTest")
    @CatchErr(write2response = true)
    public ResultMsg<Void> runTest(@RequestParam String invokeTarget, @RequestParam String description) throws Exception {
    	SysScheduleJob sysScheduleJob = new SysScheduleJob();
    	sysScheduleJob.setId(IdUtil.getSuid());
    	sysScheduleJob.setInvokeTarget(invokeTarget);
    	sysScheduleJob.setDescription(description);
    	sysScheduleJob.setConcurrent(true);//不必去加锁，直接测试执行
    	try{
    		ScheduleUtil.jobTask(sysScheduleJob).execute();
    		return new ResultMsg<>(null);
    	}catch(Exception e) {
    		return new ResultMsg<>(BaseStatusCode.PARAM_ILLEGAL, "任务配置有误！");
    	}
    }

    /**
     * 执行计划日志列表
     *
     * @param jobId   任务编号
     * @param request
     * @return
     */
    @RequestMapping("log/list")
    @CatchErr(write2response = true)
    public PageResult<?> listSysScheduleJobLog(@RequestParam("jobId") String jobId, HttpServletRequest request) {
        QueryFilter queryFilter = getQueryFilter(request);
        queryFilter.addFilter("job_id", jobId, QueryOP.EQUAL);
        return new PageResult<SysScheduleJobLog>(sysScheduleJobLogManager.query(queryFilter));
    }

    /**
     * 执行计划详细日志
     * @param id
     *          日志ID
     * @return
     */
    @RequestMapping("log/detail")
    @CatchErr(write2response = true)
    public ResultMsg<?> getLogDetail(@RequestParam("id")String id){
       SysScheduleJobLog sysScheduleJobLog = sysScheduleJobLogManager.get(id);
       return new ResultMsg<>(sysScheduleJobLog);
    }

	@Override
	protected String getModelDesc() {
		return "定时任务";
	}
}
